home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / perl / os2perl / alarm.c < prev    next >
C/C++ Source or Header  |  1991-04-12  |  4KB  |  150 lines

  1. /*
  2.  * This software is Copyright 1989 by Jack Hudler.
  3.  *
  4.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  5.  * use this software as long as: there is no monetary profit gained
  6.  * specifically from the use or reproduction or this software, it is not
  7.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  8.  * included prominently in any copy made.
  9.  *
  10.  * The author make no claims as to the fitness or correctness of this software
  11.  * for any use whatsoever, and it is provided as is. Any use of this software
  12.  * is at the user's own risk.
  13.  *
  14.  */
  15.  
  16. /****************************** Module Header ******************************\
  17. * Module Name: alarm.c
  18. * Created    : 11-08-89
  19. * Author     : Jack Hudler  [jack@csccat.lonestar.org]
  20. * Copyright  : 1988 Jack Hudler.
  21. * Function   : Unix like alarm signal simulator.
  22. \***************************************************************************/
  23.  
  24. /* Tested using OS2 1.2 with Microsoft C 5.1 and 6.0. */
  25.  
  26. #define INCL_DOSPROCESS
  27. #define INCL_DOSSIGNALS
  28. #define INCL_DOS
  29. #include <os2.h>
  30.  
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <signal.h>
  34.  
  35. #include "alarm.h"
  36.  
  37. #define ALARM_STACK 4096    /* This maybe over kill, but the page size is 4K */
  38.  
  39. static  PBYTE     pbAlarmStack;
  40. static  SEL       selAlarmStack;
  41. static  TID       tidAlarm;
  42. static  PID       pidMain;
  43. static  BOOL      bAlarmInit=FALSE;
  44. static  BOOL      bAlarmRunning=FALSE;
  45. static  USHORT    uTime;
  46.  
  47. static VOID FAR alarm_thread ( VOID )
  48. {
  49.     while(1)
  50.     {
  51.       if (bAlarmRunning)
  52.       {
  53.         DosSleep(1000L);
  54.         uTime--;
  55.         if (uTime==0L)
  56.         {
  57.           // send signal to the main process.. I could have put raise() here
  58.           // however that would require the use of the multithreaded library,
  59.           // and it does not contain raise()!
  60.           // I tried it with the standard library, this signaled ok, but a
  61.           // test printf in the signal would not work and even caused SEGV.
  62.           // So I signal the process through OS/2 and then the process
  63.           // signals itself.
  64.           if (bAlarmRunning)
  65.             DosFlagProcess(pidMain,FLGP_PID, PFLG_A,1);
  66.           bAlarmRunning=FALSE;
  67.         }
  68.       }
  69.       else
  70.         DosSleep(500L);
  71.     }
  72. }
  73.  
  74. static VOID PASCAL FAR AlarmSignal(USHORT usSigArg,USHORT usSigNum)
  75. {
  76.     /*
  77.      * this is not executed from the thread. The thread triggers Process
  78.      * flag A which is in the main processes scope, this inturn triggers
  79.      * (via the raise) SIGUSR1 which is defined to SIGALRM.
  80.      */
  81.     raise(SIGUSR1);
  82. }
  83.  
  84. static void alarm_init(void)
  85. {
  86.     PFNSIGHANDLER pfnPrev;
  87.     USHORT       pfAction;
  88.     PIDINFO      pid;
  89.  
  90.     bAlarmInit = TRUE;
  91.  
  92.     if (!DosAllocSeg( ALARM_STACK, (PSEL) &selAlarmStack, SEG_NONSHARED ))
  93.     {
  94.       OFFSETOF(pbAlarmStack) = ALARM_STACK - 2;
  95.       SELECTOROF(pbAlarmStack) = selAlarmStack;
  96.       /* Create the thread */
  97.       if (DosCreateThread( alarm_thread, &tidAlarm, pbAlarmStack ))
  98.       {
  99.         fprintf(stderr,"Alarm thread failed to start.\n");
  100.         exit(1);
  101.       }
  102.       /* Setup the signal handler for Process Flag A */
  103.       if (DosSetSigHandler(AlarmSignal,&pfnPrev,&pfAction,SIGA_ACCEPT,SIG_PFLG_A))
  104.       {
  105.         fprintf(stderr,"SigHandler Failed to install.\n");
  106.         exit(1);
  107.       }
  108.       /* Save main process ID, we'll need it for triggering the signal */
  109.       DosGetPID(&pid);
  110.       pidMain = pid.pid;
  111.     }
  112.     else
  113.       exit(1);
  114. }
  115.  
  116. unsigned alarm(unsigned sec)
  117. {
  118.     if (!bAlarmInit) alarm_init();
  119.  
  120.     if (sec)
  121.     {
  122.       uTime = sec;
  123.       bAlarmRunning = TRUE;
  124.     }
  125.     else
  126.       bAlarmRunning = FALSE;
  127.  
  128.     return 0;
  129. }
  130.  
  131. #ifdef TESTING
  132. /* A simple test to see if it works */
  133. BOOL  x;
  134.  
  135. void timeout(void)
  136. {
  137.     fprintf(stderr,"ALARM TRIGGERED!!\n");
  138.     DosBeep(1000,500);
  139.     x++;
  140. }
  141.  
  142. void main(void)
  143. {
  144.     (void) signal(SIGALRM, timeout);
  145.     (void) alarm(1L);
  146.     printf("ALARM RUNNING!!\n");
  147.     while(!x);
  148. }
  149. #endif
  150.